package com.basker.pisces.domain.entity.meta;

import java.util.List;

import com.basker.pisces.IChild;
import com.basker.pisces.core.meta.ICollectionField;
import com.basker.pisces.core.meta.IDataObjectMeta;
import com.basker.pisces.core.meta.IField;
import com.basker.pisces.core.meta.utils.DataObjectMetaUtils;
import com.basker.pisces.domain.property.meta.ReferenceProperty;
import com.basker.pisces.exception.ExceptionFactory;

public abstract class ChildEntity extends AbstractEntity implements IChild<AbstractEntity> {
    private transient AbstractEntity parentEntity;
    private transient ICollectionField field;

    public ChildEntity() {

    }

    public void bindField(IDataObjectMeta objectMeta) {
        IField field = DataObjectMetaUtils.tryFindField(objectMeta, this.getName());

        if (field instanceof ICollectionField) {
            ICollectionField collectionField = (ICollectionField) field;

            this.field = collectionField;
            this.dataObjectMeta = collectionField.getItemObjectMeta();
        } else {
            throw ExceptionFactory.createRuntimeException("pisces-domain.ChildEntity.bindField-001",
                    "child entity:{0}'s field not found in objectMeta:{1}", this.getName(), objectMeta.toString());
        }

    }

    public ICollectionField getField() {
        return field;
    }

    public AbstractEntity getParentEntity() {
        return parentEntity;
    }

    public void setParentEntity(AbstractEntity parentEntity) {
        this.parentEntity = parentEntity;
    }

    public List<Object> getValue(Object dataObject) {
        return (List<Object>) this.field.getValue(dataObject);
    }

    /**
     * 等同于 {@link #setParentEntity(AbstractEntity)}
     */
    @Override
    public void setParent(AbstractEntity parentEntity) {
        this.parentEntity = parentEntity;
    }

    @Override
    protected Entity findReferenceRootEntity(final ReferenceProperty referenceProperty) {
        return this.findRoot().findReferenceRootEntity(referenceProperty);
    }

    @Override
    protected Entity findRoot() {
        return this.parentEntity.findRoot();
    }
}
